#!/usr/bin/env python

# TODO
# - clearly, could probably be doing better than just doing a B+W cutoff
# 	- and if not, just use ImageMagik tools to do that
# - chase down tesseract chokes, errors

import sys
import Image
import lf_constants
import lf_base

class OcrInterface(object):
	""" Provides an interface to the OCR engine. """

	@classmethod
	def read(self, image_url): 
		"""Fetches an image and returns what tesseract
		thinks is writen inside it.

		errors: 
		_ -> choke
		l -> I
		"""
		return 'TODO'
		# TODO get image_url and save it to img_path
		system('convert "%s" -resize 700 bigemail.png' % file_path)
		self.convertFileToBandW('bigemail.png', 'bwemail.png')
		system('convert bwemail.png +compress tiffemail.tif')
		system("tesseract tiffemail.tif outputfile batch > /dev/null 2>&1 && cat outputfile.txt | sed -e 's/\s//g'")

	# Works about just as well:
	#convert two.png -resize 700 bigemail.png
	#convert bigemail.png -colorspace Gray greyscale.png
	#convert greyscale.png -threshold 44000 +compress tiffemail.tif
	#tesseract tiffemail.tif outputfile batch > /dev/null 2>&1 && cat outputfile.txt | sed -e 's/\s//g'

	# Original (doesn't wtm):
	#convert email.png -resize 700 bigemail.png
	#convert bigemail.png -threshold 44000 +compress tiffemail.tif
	#tesseract tiffemail.tif outputfile batch > /dev/null 2>&1 && cat outputfile.txt 

	def getColorFrequencyCounts(self, im):
		"""Get frequency counts of each tuple."""
		width = im.size[0] 
		height = im.size[1]
		colors = {} 
		for x in range(width):
			for y in range(height):
				coord = im.getpixel((x,y))
				if colors.has_key(coord):
					colors[coord] += 1
				else:
					colors[coord] = 1
		return colors

	def sortColorsByFrequency(self, colors):
		"""Sort color tuples by frequency."""
		try:
			sorted = []
			for k, v in colors.items():
				sorted.append((v, k[0], k[1], k[2]))
			sorted.sort()
			for entry in sorted:
				print "(%-3s, %-3s, %-3s): %5s (%.5s%%)" % \
						(entry[1], entry[2], entry[3], entry[0], entry[0]*100.0/num_pixels)
			return sorted
		except TypeError:
			raise lf_base.FacebookOcrError, "Pixels need to be tuples, not ints"

	def sortColorsByValue(self, colors):
		"""Sort color tuples by value."""
		try:
			sorted = []
			for k, v in colors.items():
				sorted.append((k[0], k[1], k[2], v))
			sorted.sort()
			for entry in sorted:
				print "(%-3s, %-3s, %-3s): %5s (%.5s%%)" % \
						(entry[0], entry[1], entry[2], entry[3], entry[3]*100.0/num_pixels)
			return sorted
		except TypeError:
			raise lf_base.FacebookOcrError, "Pixels need to be tuples, not ints"

	def convertImageToBandW(self, im, data):
		"""Set all pixels as either white or black according to the threshold value."""
		width = im.size[0] 
		height = im.size[1]
		num_pixels = width * height
		whites = blacks = 0
		for i in range(num_pixels):
			if data[i] > lf_constants.OCR_THRESHOLD_VALUE:
				data[i] = lf_constants.OCR_WHITE_COLOR_VALUE
				whites += 1
			else: 
				data[i] = lf_constants.OCR_BLACK_COLOR_VALUE
				blacks += 1
		return whites, blacks

	def convertFileToBandW(self, infile, outfile):
		"""Read in a file, and write a B and W copy."""
		orig = Image.open(infile)
		im = orig.copy()
		data = list(im.getdata())
		self.convertImageToBandW(im, data)
		im.putdata(data)
		im.save(outfile)

if __name__ == '__main__':
	if len(sys.argv) < 3:
		print "Usage: lf_ocr.py infile outfile [freq] [verbose] [value]"
		exit(0)

	ocri = OcrInterface()
	infile = sys.argv[1]
	outfile = sys.argv[2]
	orig = Image.open(infile)
	im = orig.copy()
	width = im.size[0] 
	height = im.size[1]
	num_pixels = width * height
	data = list(im.getdata())

	if 'freq' in sys.argv or 'value' in sys.argv:
		colors = ocri.getColorFrequencyCounts(im)

	if 'freq' in sys.argv:
		ocri.sortColorsByFrequency(colors)

	if 'value' in sys.argv:
		ocri.sortColorsByValue(colors)

	whites, blacks = ocri.convertImageToBandW(im, data)

	if 'verbose' in sys.argv:
		print "Whites: %5s (%.5s%%)" % (whites, whites*100.0/num_pixels)
		print "Blacks: %5s (%.5s%%)" % (blacks, blacks*100.0/num_pixels)

	im.putdata(data)
	im.save(outfile)
